<script setup lang="tsx">
import { ref, reactive, unref, provide, onMounted } from 'vue'
import { ContentWrap } from '@/components/ContentWrap'
import { Search } from '@/components/Search'
import { Table } from '@/components/Table'
import { ElCollapseTransition, ElDialog, ElButton } from 'element-plus'
import { useTable } from '@/hooks/web/useTable'
import { BaseButton } from '@/components/Button'
import XLSXS from 'xlsx-js-style'
import { onPrint } from '@/utils/print'
import { CrudSchema, useCrudSchemas } from '@/hooks/web/useCrudSchemas'
import { getListApi, detailsApi, linePrintApi, lineDowApi } from '@/api/sorting'

defineOptions({
  name: 'Sorting'
})

const crudSchemas = reactive<CrudSchema[]>([
  {
    field: 'selection',
    search: { hidden: true },
    form: { hidden: true },
    detail: { hidden: true },
    type: 'selection'
  },
  {
    field: 'name',
    label: '文件名称',
    form: { hidden: true },
    detail: { hidden: true }
  },
  {
    field: 'create_time',
    label: '文件生成时间',
    search: {
      component: 'DatePicker',
      componentProps: {
        type: 'daterange',
        valueFormat: 'YYYY-MM-DD'
      }
    },
    form: { hidden: true },
    detail: { hidden: true }
  },
  {
    field: 'pick_time',
    label: '用户提货时间',
    search: { hidden: true },
    form: { hidden: true },
    detail: { hidden: true }
  },
  {
    field: 'is_dow',
    label: '是否下载',
    search: { hidden: true },
    form: { hidden: true },
    detail: { hidden: true },
    formatter: (cellValue) => {
      return cellValue.is_dow_text
    }
  },
  {
    field: 'is_print',
    label: '是否打印',
    search: { hidden: true },
    form: { hidden: true },
    detail: { hidden: true },
    formatter: (cellValue) => {
      return cellValue.is_print_text
    }
  },
  {
    field: 'dow_time',
    label: '上次下载时间',
    search: { hidden: true },
    form: { hidden: true },
    detail: { hidden: true }
  },
  {
    field: 'print_time',
    label: '上次打印时间',
    search: { hidden: true },
    form: { hidden: true },
    detail: { hidden: true }
  },

  {
    field: 'action',
    label: '操作',
    width: '260px',
    search: { hidden: true },
    form: { hidden: true },
    detail: { hidden: true },
    slots: {
      default: ({ row }) => {
        return (
          <>
            <BaseButton type="primary" onClick={() => taskDown(row)}>
              下载
            </BaseButton>
            <BaseButton type="primary" onClick={() => getDetailsApi(row)}>
              预览
            </BaseButton>
          </>
        )
      }
    }
  }
])
// @ts-ignore
const { allSchemas } = useCrudSchemas(crudSchemas)
const row_id = ref('')
const searchParams = ref({})
const setSearchParams = (params: any) => {
  searchParams.value = params
  getList()
}

const { tableRegister, tableState, tableMethods } = useTable({
  fetchDataApi: async () => {
    const { currentPage, pageSize } = tableState
    const res = await getListApi({
      page: unref(currentPage),
      limit: unref(pageSize),
      ...unref(searchParams)
    })
    return {
      list: res.data.list,
      total: res.data.count
    }
  }
})
const { loading, dataList, total, currentPage, pageSize } = tableState
const { getList, getElTableExpose, delList } = tableMethods
let currentRow = reactive<any>({})
const dialogFormVisible = ref(false)

const taskDownList = ref()
// 打印预览
const getDetailsApi = async (val) => {
  row_id.value = val.id
  const res = await detailsApi({ id: val.id })
  taskDownList.value = res.data.info
  dialogFormVisible.value = true
}
// 打印
const handlePrint = () => {
  // const nowTime = parseTime(new Date())
  // const header = `
  //         <div>
  //           <p style="display: inline-block;text-align: center;">打印时间：${taskDownList.value.printInfo.p_time || nowTime}</p>
  //           <p style="display: inline-block;float: right;">${taskDownList.value.printInfo.p_number || ''}</p>
  //         </div>
  //       `
  const watermarkTemplate = `
        <div style="position: relative;display: flex;align-items: center;gap: 20px;z-index: -999;">
            <span>${taskDownList.value.company_name}</span>
        </div>
      `
  onPrint('#printMe', {
    watermark: watermarkTemplate,
    // header,
    font: '30px Arial',
    color: 'rgba(0,0,0, .3)',
    opacity: '30%'
  })
  if (row_id.value !== '') {
    linePrintApi({
      id: row_id.value
    })
  }
}
// 下载
const taskDown = async (val) => {
  row_id.value = val.id
  const res = await detailsApi({ id: val.id })
  taskDownList.value = res.data.info
  exportExcel(res.data.info.name, taskDownList.value)
}
const exportExcel = (excelName, excelData) => {
  const colsWidth = []
  function getCellWidth(value) {
    // 判断是否为null或undefined
    if (value == null) {
      return 10
    } else if (/.*[\u4e00-\u9fa5]+.*$/.test(value)) {
      // 中文的长度
      const chineseLength = value.match(/[\u4e00-\u9fa5]/g).length
      // 其他不是中文的长度
      const otherLength = value.length - chineseLength
      return chineseLength * 2.1 + otherLength * 1.1
    } else {
      return value.toString().length * 1.1
    }
  }
  function handleUserData(data) {
    const result = [
      [
        {
          v: data.name,
          t: 's',
          s: {
            font: {
              name: '宋体',
              sz: 14,
              bold: true,
              color: { rgb: '000000' }
            },
            fill: { fgColor: { rgb: 'D9D9D9' } },
            alignment: { vertical: 'center', horizontal: 'center' }
          }
        }
      ],
      [
        {
          v: '用户提货日期: ' + data.pick_time,
          t: 's',
          s: {
            font: {
              name: '宋体',
              sz: 11,
              color: { rgb: '000000' }
            },
            alignment: {
              horizontal: 'center',
              vertical: 'center',
              wrapText: true
            }
          }
        }
      ],
      [
        {
          v: '路线编号: ' + data.line.no,
          t: 's',
          s: {
            font: {
              name: '宋体',
              sz: 11,
              color: { rgb: '000000' }
            },
            alignment: {
              horizontal: 'center',
              vertical: 'center',
              wrapText: true
            }
          }
        }
      ],
      [
        {
          v: '路线名称: ' + data.line.name,
          t: 's',
          s: {
            font: {
              name: '宋体',
              sz: 11,
              color: { rgb: '000000' }
            },
            alignment: {
              horizontal: 'center',
              vertical: 'center',
              wrapText: true
            }
          }
        }
      ],
      [
        {
          v: '门店名称',
          t: 's',
          s: {
            font: {
              name: '宋体',
              sz: 11,
              color: { rgb: '000000' }
            },
            fill: { fgColor: { rgb: 'D9D9D9' } },
            alignment: { vertical: 'center', horizontal: 'center' }
          }
        },
        {
          v: '商品名称',
          t: 's',
          s: {
            font: {
              name: '宋体',
              sz: 11,
              color: { rgb: '000000' }
            },
            fill: { fgColor: { rgb: 'D9D9D9' } },
            alignment: { vertical: 'center', horizontal: 'center' }
          }
        },
        {
          v: '规格',
          t: 's',
          s: {
            font: {
              name: '宋体',
              sz: 11,
              color: { rgb: '000000' }
            },
            fill: { fgColor: { rgb: 'D9D9D9' } },
            alignment: { vertical: 'center', horizontal: 'center' }
          }
        },
        {
          v: '商品条码',
          t: 's',
          s: {
            font: {
              name: '宋体',
              sz: 11,
              color: { rgb: '000000' }
            },
            fill: { fgColor: { rgb: 'D9D9D9' } },
            alignment: { vertical: 'center', horizontal: 'center' }
          }
        },
        {
          v: '分拣数量',
          t: 's',
          s: {
            font: {
              name: '宋体',
              sz: 11,
              color: { rgb: '000000' }
            },
            fill: { fgColor: { rgb: 'D9D9D9' } },
            alignment: { vertical: 'center', horizontal: 'center' }
          }
        }
      ]
    ]
    for (const v of data.store) {
      for (const shopListEl of v.details) {
        const params = [
          v.name || '',
          shopListEl.goods.name || '',
          shopListEl.goods_rule || '',
          shopListEl.goods.no || '',
          shopListEl.quantity || ''
        ]
        const colsList = []
        let num = 0
        for (const param of params) {
          num = getCellWidth(param)
          colsList.push(Math.floor(num * 100) / 100)
        }
        result.push(params)
        colsWidth.push(colsList)
      }
    }
    return result
  }
  function handleUserDataMerges(data) {
    let nextStartIndex = 6
    const result = []
    for (const dataEl of data.store) {
      const merges = [
        String.fromCharCode(64 + 1) +
          `${nextStartIndex}:` +
          String.fromCharCode(64 + 1) +
          `${nextStartIndex + dataEl.details.length - 1}`
      ]
      result.push(...merges)
      nextStartIndex = nextStartIndex + dataEl.details.length
    }
    return result
  }
  const userRowData = handleUserData(excelData)
  const userRowDataMerges = handleUserDataMerges(excelData)
  const wb = XLSXS.utils.book_new()
  const rowArray = [...userRowData]
  const ws = XLSXS.utils.aoa_to_sheet(rowArray)
  XLSXS.utils.book_append_sheet(wb, ws, excelName)
  let maxColumnNumber = 5 // 默认最大列数
  rowArray.map((item) => (item.length > maxColumnNumber ? (maxColumnNumber = item.length) : ''))
  // 合并单元格
  const merges = [
    'A1:' + String.fromCharCode(64 + parseInt(maxColumnNumber)) + '1',
    'A2:' + String.fromCharCode(64 + parseInt(maxColumnNumber)) + '2',
    'A3:' + String.fromCharCode(64 + parseInt(maxColumnNumber)) + '3',
    'A4:' + String.fromCharCode(64 + parseInt(maxColumnNumber)) + '4',
    ...userRowDataMerges
  ]
  const wsMerge = []
  merges.map((item) => {
    wsMerge.push(XLSXS.utils.decode_range(item))
  })
  ws['!merges'] = wsMerge
  // 边框样式
  const borderStyle = {
    top: {
      style: 'thin',
      color: {
        rgb: '000000'
      }
    },
    bottom: {
      style: 'thin',
      color: {
        rgb: '000000'
      }
    },
    left: {
      style: 'thin',
      color: {
        rgb: '000000'
      }
    },
    right: {
      style: 'thin',
      color: {
        rgb: '000000'
      }
    }
  }
  // 添加外边框
  rowArray.map((item, index) => {
    for (let i = 1; i <= maxColumnNumber; i++) {
      const row_index = String.fromCharCode(64 + parseInt(i)) + (index + 1)

      if (!ws[row_index]) {
        ws[row_index] = { v: '', t: 's', s: { border: borderStyle } }
        continue
      }
      if (!('s' in ws[row_index])) {
        ws[row_index].s = {
          border: borderStyle,
          alignment: { vertical: 'center', horizontal: 'center' }
        }
      } else {
        ws[row_index].s.border = borderStyle
      }
    }
  })
  // 添加列宽
  const wsCols = new Array(colsWidth[0].length)
  for (const colsEl of colsWidth) {
    colsEl.forEach((item, index) => {
      if (wsCols[index]) {
        wsCols[index] = wsCols[index] > item ? wsCols[index] : item
      } else {
        wsCols[index] = item > 20 ? item : 22
      }
    })
  }
  ws['!cols'] = wsCols.map((item) => ({ width: item }))
  // 添加行高
  XLSXS.writeFile(wb, excelName + '.xlsx')
  if (row_id.value !== '') {
    lineDowApi({
      id: row_id.value
    })
  }
}

provide('currentRow', currentRow)
</script>

<template>
  <ContentWrap title="分拣单列表">
    <Search :schema="allSchemas.searchSchema" @search="setSearchParams" @reset="setSearchParams" />

    <Table
      v-model:pageSize="pageSize"
      v-model:currentPage="currentPage"
      :columns="allSchemas.tableColumns"
      :data="dataList"
      :loading="loading"
      :pagination="{ total }"
      @register="tableRegister"
    />
    <el-dialog v-model="dialogFormVisible" title="打印预览">
      <div style="max-height: 50%; overflow-y: auto">
        <div class="print" id="printMe">
          <!-- 分拣单 -->
          <div style="margin: 0 auto 40px">
            <table
              style="width: 100%"
              class="table table-striped table-bordered"
              align="center"
              valign="center"
            >
              <thead>
                <th class="title" colspan="8">
                  {{ taskDownList.name }}
                </th>
                <tr>
                  <td class="value" colspan="8" align="center"
                    >用户提货日期:{{ taskDownList.pick_time }}</td
                  >
                </tr>
                <tr>
                  <td class="value" colspan="8" align="center"
                    >路线编号:{{ taskDownList.line.no }}</td
                  >
                </tr>
                <tr>
                  <td class="value" colspan="8" align="center"
                    >路线名称:{{ taskDownList.line.name }}</td
                  >
                </tr>
                <tr>
                  <td class="column">门店名称</td>
                  <td class="column">商品名称</td>
                  <td class="column">规格</td>
                  <td class="column">商品条码</td>
                  <td class="column">分拣数量</td>
                </tr>
              </thead>
              <tbody v-for="(item, index) in taskDownList.store" :key="index">
                <tr v-for="(shop, shopIndex) in item.details" :key="shopIndex">
                  <td class="value" :rowspan="item.details.length" v-if="shopIndex === 0">{{
                    item.name
                  }}</td>
                  <td class="value">{{ shop.goods.name }}</td>
                  <td class="value">{{ shop.goods_rule }}</td>
                  <td class="value">{{ shop.goods.no }}</td>
                  <td class="value">{{ shop.quantity }}</td>
                </tr>
              </tbody>
            </table>
            <p style="text-align: right; margin-right: 50px">领单人： </p>
          </div>
        </div>
        <div style="margin-left: 50px">
          <el-button type="primary" @click="handlePrint">打印</el-button>
        </div>
      </div>
    </el-dialog>
  </ContentWrap>
</template>
<style scoped>
.print {
  width: 90%;
  margin: 0 auto;
  max-width: 1280px;
}
.table {
  border-collapse: collapse;
  border-spacing: 0;
  background-color: transparent;
  display: table;
  width: 100%;
  max-width: 100%;
  width: 800px;
  margin: 0 auto;
}
.table td {
  text-align: center;
  vertical-align: middle;
  font-size: 14px;
  font-family: 'Arial Normal', 'Arial';
  color: #333333;
  padding: 8px 12px;
}
.table-bordered {
  border: 1px solid #ddd;
}
.table .title {
  font-size: 20px;
  font-weight: bold;
  text-align: center;
  border: 1px solid #333;
  background: #f1f1f1;
}
.column {
  width: 30px;
  height: 30px;
  border: 1px solid #333;
  background: #f1f1f1;
}
.column.clearBg {
  background: unset;
}
.value {
  width: 70px;
  height: 30px;
  border: 1px solid #333;
}
</style>
